#pragma once

///////////////////////////////////////
// See the MIDI specification for more
//	info on what all of these mean.
//
typedef enum MidiStatus {
	NoteOff = 8,
	MoteOn,
	PolyphonicKeyPressure,
	ControlChange,
	ProgramChange,
	ChannelPressure,
	PitchWheelChange
} MidiStatus_t;

class MidiMessage
{
public:
	MidiMessage(void) {
		_status = 0;
		_data0 = 0;
		_data1 = 0;
		_packedMessage = 0;
	}
	
	void MidiMessage::setStatus(MidiStatus_t midiStatus) {
		_status = (((midiStatus & 0xf) << 4)|_status & 0xf);
	}

	int MidiMessage::getStatus() {
		return ((_status & 0xf0) >> 4);
	}

	void MidiMessage::setChannel(unsigned char channel) {
		_status = ((_status & 0xf0)|(channel & 0xf));
	}

	int MidiMessage::getChannel() {
		return (_status & 0x0f);
	}

	void MidiMessage::setParam0(unsigned char value) {
		_data0 = value;
	}

	int MidiMessage::getParam0() {
		return _data0;
	}

	void MidiMessage::setParam1(unsigned char value) {
		_data1 = value;
	}

	int MidiMessage::getParam1() {
		return _data1;
	}

	operator long() {
		packMessage();
		return _packedMessage;
	}

	operator unsigned long() {
		packMessage();
		return _packedMessage;
	}

	~MidiMessage(void) {
	}
	
private:
	void MidiMessage::packMessage() {
		_packedMessage = 
			0 |
			_data1 << 16 |
			_data0 << 8 |
			_status;
	}

	unsigned long _packedMessage;

	unsigned char _status;
	unsigned char _data0;
	unsigned char _data1;
};

